package com.common.project.util;

import lombok.extern.log4j.Log4j2;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.List;

@Log4j2
public class FileUtil {

    /**
     * 获取文件的行数
     * @param file
     * @return
     * @throws IOException
     */
    public static int getFileLineNumber(File file) throws IOException {
        LineNumberReader lnr = new LineNumberReader(new FileReader(file));
        lnr.skip(Long.MAX_VALUE);
        int lineNo = lnr.getLineNumber() + 1;
        log.info(String.format("fileNo is %d", lineNo));
        lnr.close();
        return lineNo;
    }

    /**
     *
     * @param file  要写入数据的目标text 文件
     * @param list  有序的写入内容
     */
    public static void writeStrngToText(File file, List<String> list) throws Exception {
        if(file==null||list==null||list.size()==0){
            return;
        }
        if(!file.exists()){
            file.getParentFile().mkdirs();
        }
        file.createNewFile();

        FileWriter fw = new FileWriter(file, true);
        BufferedWriter bw = new BufferedWriter(fw);
        list.stream().forEach(s -> {
            try {
                bw.write(s);
                bw.newLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
        });

        fw.close();

    }

    /**
     *  读txt 文件 控制台打印读取内容
     * @param path  待读文件绝对路径
     * @param pointe 待读文件从那行开始读  首行是 1  pointe 不是行啊！！！
     */
    public static void readText(String path,int pointe) throws Exception {
        /**
         * model各个参数详解
         * r 代表以只读方式打开指定文件
         * rw 以读写方式打开指定文件
         * rws 读写方式打开，并对内容或元数据都同步写入底层存储设备
         * rwd 读写方式打开，对文件内容的更新同步更新至底层存储设备
         *
         * **/
        RandomAccessFile raf=new RandomAccessFile(path, "rw");
        long length = raf.length();

        raf.seek(pointe);//移动文件指针位置
        byte[]  buff=new byte[1024];
        //用于保存实际读取的字节数
        int hasRead=0;
        //循环读取
        while((hasRead=raf.read(buff))>0){
            //打印读取的内容,并将字节转为字符串输入
            System.out.println(new String(buff,0,hasRead));
        }
        raf.close();
    }


    /**
     *  从指定位置开始写入内容到txt文件，默认从最后一行开始写
     * @param path  待写入文件待位置
     * @param pointe  待写入待位置  txt 第一行是1  重点是该参数不是行数，比如文本内容：第一行 jiangshicun333 第二行 zhangsan666  pointe=3 写入一个 ABC  那么 第一行变为: jiaABCshicun333
     * @param list  待写入待每一行待数据集
     * @throws Exception
     */
    public static void writeAtAssignPointe(String path,Integer pointe,List<String> list)throws Exception{
        int xieWeiZhi=0;
        File file=new File(path);
      /*  if(!file.exists()){
            return;
        }*/
        if(list==null||list.size()==0){
            return;
        }


        /**
         * model各个参数详解
         * r 代表以只读方式打开指定文件
         * rw 以读写方式打开指定文件
         * rws 读写方式打开，并对内容或元数据都同步写入底层存储设备
         * rwd 读写方式打开，对文件内容的更新同步更新至底层存储设备
         *
         * **/
        RandomAccessFile raf=new RandomAccessFile(path, "rw");
        long length = raf.length();

        int size=list.size();
        if(pointe==null){// 如何该参赛为null, 那么则从文件待最后一行开始写
            xieWeiZhi = Integer.parseInt(size+"")+1;
//            xieWeiZhi = getFileLineNumber(file)+1;
        }else{
            xieWeiZhi=pointe;
        }


        raf.seek(xieWeiZhi);

        //***************先将插入点后面的内容保存起来****************
        StringBuffer sb = new StringBuffer();
         byte[] b = new byte[100];
         int len;
         while( (len=raf.read(b)) != -1 ) {
                sb.append( new String(b, 0, len) );
              }
         //.................................................
//        int newXieWeiZhi=(xieWeiZhi-1)+size;
        int newXieWeiZhi=xieWeiZhi;
        raf.seek(newXieWeiZhi); //重新设置插入位置
        //插入指定内容
        list.stream().forEach(s -> {
            try {
                raf.writeBytes("\r\n");
                raf.write(s.getBytes());

            } catch (IOException e) {
                e.printStackTrace();
            }
        });
        //恢复插入点后面的内容
        raf.write( sb.toString().getBytes() );
        raf.close();
    }

    /**
     *  把字符串写入到txt 文件
     * @param path
     * @param str
     */
    public static void writeStringToText (String path,String str) throws IOException {

        BufferedWriter out = new BufferedWriter(
                new OutputStreamWriter(new FileOutputStream(path,true)));
        out.write("\r\n");
        out.write(str);
        out.close();

    }


    public static void copy(File file, File toFile) throws Exception {
        byte[] b = new byte[1024];
        int a;
        FileInputStream fis;
        FileOutputStream fos;
        if (file.isDirectory()) {
            String filepath = file.getAbsolutePath();
            filepath=filepath.replaceAll("\\\\", "/");
            String toFilepath = toFile.getAbsolutePath();
            toFilepath=toFilepath.replaceAll("\\\\", "/");
            int lastIndexOf = filepath.lastIndexOf("/");
            toFilepath = toFilepath + filepath.substring(lastIndexOf ,filepath.length());
            File copy=new File(toFilepath);
            //复制文件夹
            if (!copy.exists()) {
                copy.mkdir();
            }
            //遍历文件夹
            for (File f : file.listFiles()) {
                copy(f, copy);
            }
        } else {
            if (toFile.isDirectory()) {
                String filepath = file.getAbsolutePath();
                filepath=filepath.replaceAll("\\\\", "/");
                String toFilepath = toFile.getAbsolutePath();
                toFilepath=toFilepath.replaceAll("\\\\", "/");
                int lastIndexOf = filepath.lastIndexOf("/");
                toFilepath = toFilepath + filepath.substring(lastIndexOf ,filepath.length());

                //写文件
                File newFile = new File(toFilepath);
                fis = new FileInputStream(file);
                fos = new FileOutputStream(newFile);
                while ((a = fis.read(b)) != -1) {
                    fos.write(b, 0, a);
                }
            } else {
                //写文件
                fis = new FileInputStream(file);
                fos = new FileOutputStream(toFile);
                while ((a = fis.read(b)) != -1) {
                    fos.write(b, 0, a);
                }
            }

        }
    }
    private static int a = 5;

    public static void main(String[] args) {
        //需要复制的目标文件或目标文件夹
        String pathname = "C:/Users/likun/Desktop/git_project";
        File file = new File(pathname);
        //复制到的位置
        String topathname = "C:/Users/likun/Desktop/movie";
        File toFile = new File(topathname);
        try {
            copy(file, toFile);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    /**
     *
     * @param file 文件
     * @param realPath 文件存放路径
     * @param fileName 源文件名
     * @return
     */
    public static boolean upload(MultipartFile file, String realPath){

        // 生成新的文件名
        //String realPath = path + "/" + FileNameUtils.getFileName(fileName);


        File dest = new File(realPath);

        //判断文件父目录是否存在
        if(!dest.getParentFile().exists()){
            dest.getParentFile().mkdir();
        }

        try {
            //保存文件
            file.transferTo(dest);
            return true;
        } catch (IllegalStateException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        }

    }


}
